// Copyright (C) 1953-2021 NUDT
// Verilog module name - tss_command_parse
// Version: V3.3.0.20211124
// Created:
//         by - fenglin 
////////////////////////////////////////////////////////////////////////////
// Description:
//         Command Parse
///////////////////////////////////////////////////////////////////////////

`timescale 1ns/1ps

module tss_command_parse
#(parameter INDEX_HCP = 20, 
            PORT_NUM = 21
)
(
        i_clk,
        i_rst_n,
        
        iv_command  ,   
        i_command_wr,           
        
        ov_addr     ,
        ov_wdata    ,

        o_wr_ffi,
        o_rd_ffi,
        o_wr_dex,
        o_rd_dex,
                   
        o_wr_grm   ,
        o_rd_grm   ,        
        
        o_wr_flt   ,
        o_rd_flt   ,
        
        o_wr_pcb   ,
        o_rd_pcb   ,
        
        o_wr_trl   ,
        o_rd_trl   ,
        
        o_wr_idc   ,
        o_rd_idc   ,        

        o_wr_ist   ,
        o_rd_ist   ,	        
        
        o_wr_qgc  ,
        o_rd_qgc  ,
  
        o_wr_mac  ,
        o_rd_mac  , 

        o_wr_tau     ,
        o_rd_tau               
    );

// I/O
// clk & rst
input                   i_clk;
input                   i_rst_n;
           
input       [63:0]      iv_command;   
input                   i_command_wr;           
  
output  reg [18:0]      ov_addr;
output  reg [31:0]      ov_wdata;
//to all 
output  reg [PORT_NUM-1:0]      o_wr_ffi;
output  reg [PORT_NUM-1:0]      o_rd_ffi;
output  reg [PORT_NUM-1:0]      o_wr_dex;
output  reg [PORT_NUM-1:0]      o_rd_dex;
//to grm 
output  reg             o_wr_grm;
output  reg             o_rd_grm;	
//to flt 
output  reg             o_wr_flt;
output  reg             o_rd_flt;
//to pcb 
output  reg             o_wr_pcb;
output  reg             o_rd_pcb;
//to trl 
output  reg             o_wr_trl;
output  reg             o_rd_trl;
//to idc 
output  reg             o_wr_idc;
output  reg             o_rd_idc;
//to ist 
output  reg             o_wr_ist;
output  reg             o_rd_ist;	
//to qgc 
output  reg [PORT_NUM-2:0]            o_wr_qgc;
output  reg [PORT_NUM-2:0]            o_rd_qgc;

output  reg [PORT_NUM-2:0]            o_wr_mac  ;
output  reg [PORT_NUM-2:0]            o_rd_mac  ; 
                        
output  reg             o_wr_tau     ;
output  reg             o_rd_tau     ;

always @(posedge i_clk or negedge i_rst_n) begin
    if(i_rst_n == 1'b0)begin
		ov_addr                   <= 19'b0;
        ov_wdata                  <= 32'b0;

       o_wr_ffi [INDEX_HCP]              <= 1'b0;
        o_rd_ffi[INDEX_HCP]                <= 1'b0;
        o_wr_dex [INDEX_HCP]               <= 1'b0;
        o_rd_dex [INDEX_HCP]               <= 1'b0;

        o_wr_grm                  <= 1'b0 ;
        o_rd_grm                  <= 1'b0 ;
        o_wr_flt                  <= 1'b0 ;
        o_rd_flt                  <= 1'b0 ;
        o_wr_pcb                  <= 1'b0 ;
        o_rd_pcb                  <= 1'b0 ;
        o_wr_trl                  <= 1'b0 ;
        o_rd_trl                  <= 1'b0 ;
        o_wr_idc                  <= 1'b0 ;
        o_rd_idc                  <= 1'b0 ;                
        o_wr_ist                  <= 1'b0 ;
        o_rd_ist                  <= 1'b0 ;  
//        o_wr_qgc                 <= 32'b0 ;
//        o_rd_qgc                 <= 32'b0 ;
//
//        o_wr_mac  <= 32'b0 ;
//        o_rd_mac  <= 32'b0 ;
        
        o_wr_tau     <= 1'b0 ;
        o_rd_tau     <= 1'b0 ;
	end
    else begin
        if(i_command_wr == 1'b1)begin
            ov_addr          <= iv_command[50:32];
            ov_wdata         <= iv_command[31:0];
            if(iv_command[57:51] == 7'd0)begin// hcp psc
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_ffi[INDEX_HCP]            <= 1'b1;
                    o_rd_ffi[INDEX_HCP]            <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_ffi[INDEX_HCP]            <= 1'b0;
                    o_rd_ffi[INDEX_HCP]            <= 1'b1;
                end
                else begin
                    o_wr_ffi[INDEX_HCP]            <= 1'b0;
                    o_rd_ffi[INDEX_HCP]            <= 1'b0;
                end                    
            end
            else if(iv_command[57:51] == 7'd1)begin// hcp pdg
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_dex[INDEX_HCP]            <= 1'b1;
                    o_rd_dex[INDEX_HCP]            <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_dex[INDEX_HCP]            <= 1'b0;
                    o_rd_dex[INDEX_HCP]            <= 1'b1;
                end
                else begin
                    o_wr_dex[INDEX_HCP]            <= 1'b0;
                    o_rd_dex[INDEX_HCP]            <= 1'b0;
                end                    
            end

            else if(iv_command[57:51] == 7'h78 )begin//flowid forward table of forward lookup table.
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_flt             <= 1'b1;
                    o_rd_flt             <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_flt             <= 1'b0;
                    o_rd_flt             <= 1'b1;
                end
                else begin
                    o_wr_flt             <= 1'b0;
                    o_rd_flt             <= 1'b0;
                end                    
            end
            else if(iv_command[57:51] == 7'h79)begin//pcb
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_pcb             <= 1'b0;
                    o_rd_pcb             <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_pcb             <= 1'b0;
                    o_rd_pcb             <= 1'b1;
                end
                else begin
                    o_wr_pcb             <= 1'b0;
                    o_rd_pcb             <= 1'b0;
                end                                   
            end
            else if(iv_command[57:51] == 7'h7A)begin//grm
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_grm             <= 1'b1;
                    o_rd_grm             <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_grm             <= 1'b0;
                    o_rd_grm             <= 1'b1;
                end
                else begin
                    o_wr_grm             <= 1'b0;
                    o_rd_grm             <= 1'b0;
                end                                   
            end            

            else if(iv_command[57:51] == 7'h7B)begin//trl
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_trl             <= 1'b1;
                    o_rd_trl             <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_trl             <= 1'b0;
                    o_rd_trl             <= 1'b1;
                end
                else begin
                    o_wr_trl             <= 1'b0;
                    o_rd_trl             <= 1'b0;
                end                    
            end
            else if(iv_command[57:51] == 7'h7C)begin//idc
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_idc             <= 1'b1;
                    o_rd_idc             <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_idc             <= 1'b0;
                    o_rd_idc             <= 1'b1;
                end
                else begin
                    o_wr_idc             <= 1'b0;
                    o_rd_idc             <= 1'b0;
                end                    
            end            
            else begin
                //o_wr_ffi               <= PORT_NUM{1'b0};
                //o_rd_ffi               <= PORT_NUM{1'b0};
                //o_wr_dex               <= PORT_NUM{1'b0};
                //o_rd_dex               <= PORT_NUM{1'b0};
                       
                o_wr_grm                  <= 1'b0 ;
                o_rd_grm                  <= 1'b0 ;
                o_wr_flt                  <= 1'b0 ;
                o_rd_flt                  <= 1'b0 ;
                o_wr_pcb                  <= 1'b0 ;
                o_rd_pcb                  <= 1'b0 ;
                o_wr_trl                  <= 1'b0 ;
                o_rd_trl                  <= 1'b0 ;
                o_wr_idc                  <= 1'b0 ;
                o_rd_idc                  <= 1'b0 ;                
                o_wr_ist                  <= 1'b0 ;
                o_rd_ist                  <= 1'b0 ;                
                //o_wr_qgc                 <= PORT_NUM{1'b0} ;
                //o_rd_qgc                 <= PORT_NUM{1'b0} ;
 
                //o_wr_mac  <= PORT_NUM{1'b0} ;
                //o_rd_mac  <= PORT_NUM{1'b0} ;
        
                o_wr_tau     <= 1'b0 ;
                o_rd_tau     <= 1'b0 ;                
            end                
        end
        else begin
            ov_addr                   <= 19'b0;
            ov_wdata                  <= 32'b0;

            //o_wr_ffi_p               <= 1'b0;
            //o_rd_ffi_p               <= 1'b0;
            //o_wr_dex_p               <= 1'b0;
            //o_rd_dex_p               <= 1'b0;
                     
            o_wr_grm                  <= 1'b0 ;
            o_rd_grm                  <= 1'b0 ;
            o_wr_flt                  <= 1'b0 ;
            o_rd_flt                  <= 1'b0 ;
            o_wr_pcb                  <= 1'b0 ;
            o_rd_pcb                  <= 1'b0 ;
            o_wr_trl                  <= 1'b0 ;
            o_rd_trl                  <= 1'b0 ;
            o_wr_idc                  <= 1'b0 ;
            o_rd_idc                  <= 1'b0 ;                
            o_wr_ist                  <= 1'b0 ;
            o_rd_ist                  <= 1'b0 ;              
            //o_wr_qgc                 <= 1'b0 ;
            //o_rd_qgc                 <= 1'b0 ;

            //o_wr_mac  <= 1'b0 ;
            //o_rd_mac  <= 1'b0 ;
            
            o_wr_tau     <= 1'b0 ;
            o_rd_tau     <= 1'b0 ;            
        end
    end
end    

genvar i;
generate 
for(i=0; i<=7; i = i+1) begin: TSS_CMD_PARSE
always @(posedge i_clk or negedge i_rst_n) begin
    if(i_rst_n == 1'b0)begin
        o_wr_ffi[i]             <= 1'b0;
        o_rd_ffi[i]             <= 1'b0;
        o_wr_dex[i]             <= 1'b0;
        o_rd_dex[i]             <= 1'b0;

        o_wr_qgc[i]             <= 1'b0 ;
        o_rd_qgc[i]             <= 1'b0 ;

        o_wr_mac[i]  <= 1'b0 ;
        o_rd_mac[i]  <= 1'b0 ;
	end
    else begin
        if(i_command_wr == 1'b1)begin
            if(iv_command[57:51] == 7'd8+8*i) begin//ffi of ctrl port
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_ffi[i]            <= 1'b1;
                    o_rd_ffi[i]            <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_ffi[i]            <= 1'b0;
                    o_rd_ffi[i]            <= 1'b1;
                end
                else begin
                    o_wr_ffi[i]            <= 1'b0;
                    o_rd_ffi[i]            <= 1'b0;
                end                    
            end
            else if(iv_command[57:51] == 7'd9+8*i)begin//dex of ctrl port
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_dex[i]            <= 1'b1;
                    o_rd_dex[i]            <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_dex[i]            <= 1'b0;
                    o_rd_dex[i]            <= 1'b1;
                end
                else begin
                    o_wr_dex[i]            <= 1'b0;
                    o_rd_dex[i]            <= 1'b0;
                end                    
            end
			else if(iv_command[57:51] == 7'd12+8*i)begin//dex of ctrl port
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_qgc[i]            <= 1'b1;
                    o_rd_qgc[i]            <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_qgc[i]            <= 1'b0;
                    o_rd_qgc[i]            <= 1'b1;
                end
                else begin
                    o_wr_qgc[i]            <= 1'b0;
                    o_rd_qgc[i]            <= 1'b0;
                end                    
            end
            else if(iv_command[57:51] == 7'd15+8*i)begin//mac p0
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_mac[i]            <= 1'b1;
                    o_rd_mac[i]            <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_mac[i]            <= 1'b0;
                    o_rd_mac[i]            <= 1'b1;
                end
                else begin
                    o_wr_mac[i]            <= 1'b0;
                    o_rd_mac[i]            <= 1'b0;
                end                    
            end            
            else begin
                o_wr_ffi[i]             <= 1'b0;
                o_rd_ffi[i]             <= 1'b0;
                o_wr_dex[i]             <= 1'b0;
                o_rd_dex[i]             <= 1'b0;

                o_wr_qgc[i]             <= 1'b0 ;
                o_rd_qgc[i]             <= 1'b0 ;

                o_wr_mac[i]  <= 1'b0 ;
                o_rd_mac[i]  <= 1'b0 ;            
            end                
        end
        else begin
            o_wr_ffi[i]             <= 1'b0;
            o_rd_ffi[i]             <= 1'b0;
            o_wr_dex[i]             <= 1'b0;
            o_rd_dex[i]             <= 1'b0;

            o_wr_qgc[i]             <= 1'b0 ;
            o_rd_qgc[i]             <= 1'b0 ;

            o_wr_mac[i]  <= 1'b0 ;
            o_rd_mac[i]  <= 1'b0 ;        
        end
    end
end    
end
endgenerate

generate 
for(i=8; i<=PORT_NUM-2; i = i+1) begin: TSS_CMD_PARSE_part2
always @(posedge i_clk or negedge i_rst_n) begin
    if(i_rst_n == 1'b0)begin
        o_wr_ffi[i]             <= 1'b0;
        o_rd_ffi[i]             <= 1'b0;
        o_wr_dex[i]             <= 1'b0;
        o_rd_dex[i]             <= 1'b0;

        o_wr_qgc[i]             <= 1'b0 ;
        o_rd_qgc[i]             <= 1'b0 ;

        o_wr_mac[i]  <= 1'b0 ;
        o_rd_mac[i]  <= 1'b0 ;
	end
    else begin
        if(i_command_wr == 1'b1)begin
            if(iv_command[57:51] == 7'h48+4*(i-8)) begin//ffi of ctrl port
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_ffi[i]            <= 1'b1;
                    o_rd_ffi[i]            <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_ffi[i]            <= 1'b0;
                    o_rd_ffi[i]            <= 1'b1;
                end
                else begin
                    o_wr_ffi[i]            <= 1'b0;
                    o_rd_ffi[i]            <= 1'b0;
                end                    
            end
            else if(iv_command[57:51] == 7'h49+4*(i-8))begin//dex of ctrl port
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_dex[i]            <= 1'b1;
                    o_rd_dex[i]            <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_dex[i]            <= 1'b0;
                    o_rd_dex[i]            <= 1'b1;
                end
                else begin
                    o_wr_dex[i]            <= 1'b0;
                    o_rd_dex[i]            <= 1'b0;
                end                    
            end
			else if(iv_command[57:51] == 7'h4A+4*(i-8))begin//dex of ctrl port
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_qgc[i]            <= 1'b1;
                    o_rd_qgc[i]            <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_qgc[i]            <= 1'b0;
                    o_rd_qgc[i]            <= 1'b1;
                end
                else begin
                    o_wr_qgc[i]            <= 1'b0;
                    o_rd_qgc[i]            <= 1'b0;
                end                    
            end
            else if(iv_command[57:51] == 7'h4B+4*(i-8))begin//mac p0
                if(iv_command[63:62] == 2'b00)begin//write
                    o_wr_mac[i]            <= 1'b1;
                    o_rd_mac[i]            <= 1'b0;
                end
                else if(iv_command[63:62] == 2'b10)begin//read
                    o_wr_mac[i]            <= 1'b0;
                    o_rd_mac[i]            <= 1'b1;
                end
                else begin
                    o_wr_mac[i]            <= 1'b0;
                    o_rd_mac[i]            <= 1'b0;
                end                    
            end            
            else begin
                o_wr_ffi[i]             <= 1'b0;
                o_rd_ffi[i]             <= 1'b0;
                o_wr_dex[i]             <= 1'b0;
                o_rd_dex[i]             <= 1'b0;

                o_wr_qgc[i]             <= 1'b0 ;
                o_rd_qgc[i]             <= 1'b0 ;

                o_wr_mac[i]  <= 1'b0 ;
                o_rd_mac[i]  <= 1'b0 ;            
            end                
        end
        else begin
            o_wr_ffi[i]             <= 1'b0;
            o_rd_ffi[i]             <= 1'b0;
            o_wr_dex[i]             <= 1'b0;
            o_rd_dex[i]             <= 1'b0;

            o_wr_qgc[i]             <= 1'b0 ;
            o_rd_qgc[i]             <= 1'b0 ;

            o_wr_mac[i]  <= 1'b0 ;
            o_rd_mac[i]  <= 1'b0 ;        
        end
    end
end    
end
endgenerate

endmodule
